//
//  MLActionHelper.m
//  hehe
//
//  Created by Robin on 16/1/31.
//  Copyright © 2016年 HolyShit. All rights reserved.
//

#import "MYActionHelper.h"
#import "TMCache.h"
#import "GCDObjC.h"
#import "NSDictionary+MYExtend.h"

@interface MLActionHelper ()

@property(nonatomic,assign)BOOL cacheEnable;
@property(nonatomic,assign)BOOL dataFromCache;

@property(nonatomic,copy)NSString *HOST_URL;//服务端域名:端口
@property(nonatomic,copy)NSString *CLIENT;//自定义客户端识别
@property(nonatomic,copy)NSString *CODE_KEY;//错误码key,支持路径 如 data/code
@property(nonatomic,assign)NSUInteger RIGHT_CODE;//正确校验码
@property(nonatomic,copy)NSString *MSG_KEY;//消息提示msg,支持路径 如 data/msg

@end

@implementation MLActionHelper

+(MLActionHelper *)sharedHelper
{
    static dispatch_once_t onceToken;
    static MLActionHelper *helper;
    dispatch_once(&onceToken, ^{
        helper = [[MLActionHelper alloc]init];
    });
    return helper;
}

+(void)actionWithHost:(NSString *)host client:(NSString *)client codeKey:(NSString *)codeKey rightCode:(NSInteger)rightCode msgKey:(NSString *)msgKey{
    [MLActionHelper sharedHelper].HOST_URL = host;
    [MLActionHelper sharedHelper].CLIENT = client;
    [MLActionHelper sharedHelper].CODE_KEY = codeKey;
    [MLActionHelper sharedHelper].RIGHT_CODE = rightCode;
    [MLActionHelper sharedHelper].MSG_KEY = msgKey;
}

-(instancetype)init
{
    if(self = [super init]){
        //服务端的证书是苹果信任的不需要设置这些，就是不要用国内的ca证书
//        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"https" ofType:@"cer"];
//        NSData * certData =[NSData dataWithContentsOfFile:cerPath];
//        NSSet * certSet = [[NSSet alloc] initWithObjects:certData, nil];
//        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//        // 是否允许,NO-- 不允许无效的证书
//        [securityPolicy setAllowInvalidCertificates:YES];
//        // 设置证书
//        [securityPolicy setPinnedCertificates:certSet];
        // 创建请求管理者
        self.manager = [AFHTTPSessionManager manager];
//        self.manager.securityPolicy = securityPolicy;
        // 设置请求ContentType
        self.manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"application/json", @"text/json", @"text/javascript", @"text/html", @"application/vnd.api+json", nil];
        self.manager.requestSerializer = [AFJSONRequestSerializer serializer];

    }
    return self;
}

-(void)useCache{
    _cacheEnable = YES;
}

-(void)readFromCache{
    _dataFromCache = YES;
}
-(void)notReadFromCache{
    _dataFromCache = NO;
}

-(NSURLSessionDataTask *)sendRequest:(MYRequest *)msg
{
    NSString *url = @"";
    if ([msg.PATH hasPrefix:@"http"]) {
        url = msg.PATH;
    }
    else{
        if(msg.STATICPATH){
            url = msg.STATICPATH;
        }else if(msg.SCHEME && (msg.HOST || self.HOST_URL) ){
            url = [NSString stringWithFormat:@"%@://%@",msg.SCHEME, msg.PATH];
        }else{
            url = [NSString stringWithFormat:@"http://%@%@",self.HOST_URL,msg.PATH];
        }
        if(msg.appendPathInfo){
            url = [url stringByAppendingString:msg.appendPathInfo];
        }
    }
    
    NSMutableURLRequest *request = [self.manager.requestSerializer requestWithMethod:msg.METHOD URLString:url parameters:msg.params error:nil];
    if(msg.httpHeaderFields){
        [msg.httpHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
            [request setValue:value forHTTPHeaderField:key];
        }];
    }
    if (msg.timeoutInterval != 0) {
        request.timeoutInterval = msg.timeoutInterval;
    }
    
    [self sending:msg];
    @weakify(msg,self);
    NSURLSessionDataTask *op = [self.manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        if(error == nil){
            @strongify(msg,self);
            if ([responseObject isKindOfClass:[NSArray class]]){
                msg.output = @{self.CODE_KEY : @(self.RIGHT_CODE), self.MSG_KEY : responseObject};
            }
            else{
                msg.output = responseObject;
            }
            if(_cacheEnable && [self doCheckCode:msg]){
                [[TMCache sharedCache] setObject:responseObject forKey:msg.cacheKey block:^(TMCache *cache, NSString *key, id object) {
                    NSLog(@"%@ has cached",url);
                }];
            }
            [self checkCode:msg];
        }else{
            @strongify(msg,self);
            msg.error = error;
            [self failed:msg];
        }
    }];
    
    msg.url = op.currentRequest.URL;
    msg.op = op;
    msg.output = [[TMCache sharedCache] objectForKey:msg.cacheKey];
    if (_dataFromCache == YES && msg.output !=nil) {
        [[GCDQueue mainQueue] queueBlock:^{
            @strongify(self);
            [self checkCode:msg];
        } afterDelay:0.1f];
    }
    [op resume];
    return op;
}

-(void)checkCode:(MYRequest *)msg{
    if([self doCheckCode:msg]){
        [self success:msg];
    }else{
        [self errorMsg:msg];
    }
}

- (void)errorMsg:(MYRequest *)msg{
    if([msg.output objectAtPath:self.MSG_KEY]){
        msg.message = [msg.output objectAtPath:self.MSG_KEY];
        NSLog(@"Error:%@",msg.message);
    }
    msg.state = MYRequestStateSuccess;
}


-(BOOL)doCheckCode:(MYRequest *)msg{
    if (msg.needCheckCode) {
        msg.codeKey = [msg.output objectAtPath:self.CODE_KEY];
        if([msg.output objectAtPath:self.CODE_KEY] && [[msg.output objectAtPath:self.CODE_KEY] intValue] == self.RIGHT_CODE){
            return YES;
        }
    }
    return NO;
}

-(void)sending:(MYRequest *)msg{
    msg.state = MYRequestStateSending;
}

- (void)success:(MYRequest *)msg{
    msg.message = [msg.output objectAtPath:self.MSG_KEY] ? : @"";
    msg.state = MYRequestStateSuccess;
}

- (void)failed:(MYRequest *)msg{
    if(msg.error.userInfo!= nil && [msg.error.userInfo objectForKey:@"NSLocalizedDescription"]){
        msg.message = [msg.error.userInfo objectForKey:@"NSLocalizedDescription"];
    }
    msg.state = MYRequestStateFailed;
    if (msg.error.code == -1001) {
        msg.isTimeout = YES;
    }
    NSLog(@"Failed:%@",msg.error);
}

@end
